#region Copyright 2006 - Evolution Tecnologia Ltda.
//
// Author: Rafael Franco Carvalho (rafael@Evolutiontec.com.br)
//
// All rights are reserved. Reproduction or transmission in whole or in part, in
// any form or by any means, eletronic, mechanical or otherwise, is prohibited
// without the prior written permission of the author.
//
// Filename: Cryptography.cs
#endregion

using System;
using System.Collections.Generic;
using System.Text;
using System.Security.Cryptography;
using System.IO;

namespace csharp.rad.general
{
    /// <summary>
    /// Single implementation of the <b>rijndaelAlg</b> cryptographfy
    /// </summary>
    public class Cryptography
    {
        private Byte[] encryptKey;
        private Byte[] encryptIV;

        public Byte[] EncryptKey
        {
            get
            {
                return encryptKey;
            }
            set
            {
                encryptKey = value;
            }
        }

        public Byte[] EncryptIV
        {
            get
            {
                return encryptIV;
            }
            set
            {
                encryptIV = value;
            }
        }

        public String Encrypt(String textToEncrypt)
        {
            Rijndael rijndaelAlg = Rijndael.Create();
            ICryptoTransform encrypted;
            Byte[] encryptedBytes;

            rijndaelAlg.Key = encryptKey;
            rijndaelAlg.IV = encryptIV;
            encrypted = rijndaelAlg.CreateEncryptor(rijndaelAlg.Key, rijndaelAlg.IV);
            encryptedBytes = encrypted.TransformFinalBlock(Encoding.Default.GetBytes(textToEncrypt), 0, textToEncrypt.Length);
            return Encoding.Default.GetString(encryptedBytes);
        }

        public String Decrypt(String textToDecrypt)
        {
            Rijndael rijndaelAlg = Rijndael.Create();
            ICryptoTransform decrypted;
            Byte[] encryptedBytes;
            rijndaelAlg.Key = encryptKey;
            rijndaelAlg.IV = encryptIV;
            decrypted = rijndaelAlg.CreateDecryptor(rijndaelAlg.Key, rijndaelAlg.IV);
            encryptedBytes = decrypted.TransformFinalBlock(Encoding.Default.GetBytes(textToDecrypt), 0, textToDecrypt.Length);
            return Encoding.Default.GetString(encryptedBytes);
        }

        /// <summary>
        /// The DES encrypt computation
        /// </summary>
        public String EncryptDES(String textToEncrypt)
        {
            SymmetricAlgorithm desAlg = DES.Create();
            desAlg.Key = encryptKey;
            desAlg.IV = encryptIV;
            desAlg.Mode = CipherMode.CBC;
            desAlg.Padding = PaddingMode.PKCS7;
            Byte[] encryptedBytes;
            encryptedBytes = Encoding.ASCII.GetBytes(textToEncrypt);
            MemoryStream myMemoryStream = new MemoryStream();
            CryptoStream myCryptoStream = new CryptoStream(myMemoryStream, 
                desAlg.CreateEncryptor(), CryptoStreamMode.Write);
            myCryptoStream.Write(encryptedBytes, 0, encryptedBytes.Length);
            myCryptoStream.Close();
            Byte[] desBytes;
            desBytes = myMemoryStream.ToArray();
            myMemoryStream.Close();
            return Convert.ToBase64String(desBytes, 0, desBytes.Length);
        }

        /// <summary>
        /// The DES decrypt
        /// </summary>
        public String DecryptDES(String textToDecrypt)
        {
            SymmetricAlgorithm desAlg = DES.Create();
            desAlg.Key = encryptKey;
            desAlg.IV = encryptIV;
            desAlg.Mode = CipherMode.CBC;
            desAlg.Padding = PaddingMode.PKCS7;
            Byte[] desBytes;
            desBytes = Convert.FromBase64String(textToDecrypt);
            MemoryStream myMemoryStream = new MemoryStream(desBytes);
            CryptoStream myCryptoStream = new CryptoStream(myMemoryStream,
                desAlg.CreateDecryptor(), CryptoStreamMode.Read);
            Byte[] decryptedBytes = new Byte[desBytes.Length];
            myCryptoStream.Read(decryptedBytes, 0, desBytes.Length);
            myCryptoStream.Close();
            myMemoryStream.Close();
            return Encoding.Default.GetString(decryptedBytes).TrimEnd('\0');
        }
    }

    /// <summary>
    /// The MD5Hash cryptography computation
    /// </summary>
    public static class MD5Hash
    {
        public static String Compute(String plainText)
        {
            MD5 hash;
            byte[] hashBytes;
            StringBuilder hashString = new StringBuilder();

            hash = MD5.Create();
            hashBytes = hash.ComputeHash(Encoding.Default.GetBytes(plainText));
            for (int i = 0; i < hashBytes.Length; i++)
            {
                hashString.Append(hashBytes[i].ToString("x2"));
            }
            return hashString.ToString();
        }
    }
}
